package com.wyh.common.utils;

import cn.hutool.jwt.Claims;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.wyh.common.exception.CustomException;
import org.springframework.beans.factory.annotation.Value;


import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import static com.wyh.common.enums.ResultCodeEnum.TOKEN_INVALID_ERROR;

/**
 * <p>
 *token工具类，解析token功能请自己完善
 * </p>
 *
 * @author 骸音
 * @since 2024-5-14
 */
public class TokenUtils {
    // 签发人
    private static final String ISSUER = "CQIE";
    private static final long TOKEN_EXPIRE_TIME =  60 * 1000L; // 时间戳，以毫秒计算, 1分钟
    private static final String JWT_KEY = "cqie";


    // 生成令牌
    public static String createToken(Map<String, Object> data) {
        return JWT.create()
                .withClaim("data", data) // 用唯一键作为data保存
                //.withExpiresAt(new Date(System.currentTimeMillis() + expireTime*TOKEN_EXPIRE_TIME)) // 过期时间
                .withIssuer(ISSUER) // 签发人
                .withIssuedAt(new Date()) // 签发时间
                .sign(Algorithm.HMAC256(JWT_KEY)); // 设置token密钥，这里是把自定义的JWT_KEY，也就是私钥作为sign, 在使用Security框架时无法很方便的获取密码
    }

    // 验证令牌
    public static boolean verify(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(JWT_KEY);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer(ISSUER)
                    .build(); // 获得verifier
            DecodedJWT verify = verifier.verify(token); // 验证不通过会抛出异常
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    // 解析token获取claims
    public static Claims getClaimsFromToken(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(JWT_KEY);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer(ISSUER)
                    .build(); // 获得verifier
            DecodedJWT decodedJWT = verifier.verify(token); // 验证不通过会抛出异常

            // 获取payload部分
            String payload = new String(decodedJWT.getPayload().getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);

            // 将payload转换为Claims对象
            Claims claims = new Claims();
            claims.parse(payload, StandardCharsets.UTF_8);
            return claims;
        } catch (Exception e) {
           throw new CustomException(TOKEN_INVALID_ERROR);
        }
    }
}